	package train;

	import java.util.Observable;
	import java.util.Observer;
	
	import rails.Rail;

public class Train implements Observer{
		private static int idCount = 42;
		/**
		 * Id of the train
		 */
		private int id;

		/**
		 * Size, maximum speed, current speed
		 */
		private int size;
		private int maxSpeed;
		private int currSpeed;
		
		/**
		 * The position on the rail (from jonction1 to jonction2) in a number of sections.
		 */
		private int currPosOnRail;
		
		/**
		 * The rail on which is the train.
		 */
		private Rail rail;
		
		/**
		 * Train direction. True -> from jonction1 to jonction2.
		 */
		private boolean direction;
		
		public Train (int size, int maxSpeed, boolean direction, Rail rail, int pos) {
			this.id = idCount;
			idCount++;
			this.size = size;
			this.maxSpeed = maxSpeed;
			this.currSpeed = maxSpeed;
			this.direction = direction;
			this.rail = rail;
			this.currPosOnRail = pos;
		}
		
		/**
		 *
		 * @param size The size of the train
		 * @param maxSpeed The maximum speed of the train
		 */
		public Train (int size, int maxSpeed, boolean direction, Rail rail) {
			this.id = idCount;
			idCount++;
			this.size = size;
			this.maxSpeed = maxSpeed;
			this.currSpeed = maxSpeed;
			this.direction = direction;
			
			
			/*
			 * On place le train sur les rails ouaiii
			 * on doit aussi verifier que le train est bien sur d'autres rail derriere
			 */
			this.rail = rail;
			
			if (direction){
				/*
				 * Direction 1
				 * On va de la jonction 1 a 2
				 * on se positionne en troncon size - 1 sur le rail
				*/					
				currPosOnRail = size - 1;
				
				while(this.rail.getLongueur() - 1 < currPosOnRail) {
					/*
					 * On decremente le taille pour voir si il peut etre sur les rails
					 */
					currPosOnRail -= this.rail.getLongueur();
					this.rail = this.rail.getjonction(2).railSuivant(this.rail);
				}
			}
			else {
				/*
				 * Direction 2
				 * On va de la jonction 2 a 1
				 * on se positionne en troncon 0 sur le rail
				*/					
				currPosOnRail = rail.getLongueur() - size;
				
				while(currPosOnRail < 0) {
					/*
					 * On decremente le taille pour voir si il peut etre sur les rails
					 */
					this.rail = this.rail.getjonction(1).railSuivant(this.rail);
					currPosOnRail += this.rail.getLongueur();
				}
			}
		}
		
		public int getId() {
			return id;
		}

		public void update(Observable arg0, Object arg1) {
			avancerTrain();
		}

		public void setCurrentSpeed(int newCurrentSpeed) {
			this.currSpeed = newCurrentSpeed;
		}
		
		public int getCurrentSpeed() {
			return this.currSpeed;
		}
		
		public int getMaxSpeed() {
			return this.maxSpeed;
		}
		
		public int getCurrPosOnRail() {
			return this.currPosOnRail;
		}
		
		public void setRail(Rail rail) {
			this.rail = rail;
		}
		
		public Rail getRail() {
			return rail;
		}
		
		public boolean getDirection() {
			return direction;
		}

		public int getSize() {
			return size;
		}

		/**
		 * Allow the train to advance on his rail depending on its speed
		 */			
		public void avancerTrain() {
			if(direction)
				currPosOnRail += currSpeed;
			else
				currPosOnRail -= currSpeed;
			
			if(currPosOnRail >= rail.getLongueur()) { //Le train est arriv� au bout du rail du c�t� jonction2.
				if(rail.getSemaphore(2) != null)
					rail.getSemaphore(2).actionOnTrain(this);
				
				if(currSpeed == 0) //Le train est arr�t� devant un feu.
					currPosOnRail = rail.getLongueur() - 1;
				else { //Le train doit changer de rail.
					if(rail.getjonction(2).railSuivant(rail) == null) { //Le train doit s'arr�ter � la but�e.
						currSpeed = 0;
						currPosOnRail = rail.getLongueur() - 1;
					}
					else {
						currPosOnRail = currPosOnRail - rail.getLongueur();
						rail.enleverTrain(this);
						rail = rail.getjonction(2).railSuivant(rail);
						rail.ajoutTrain(this);
					}
				}
				
			}
			else if(currPosOnRail < 0) { //Le train est arriv� au bout du rail du c�t� jonction2. 
				if(rail.getSemaphore(1) != null)
					rail.getSemaphore(1).actionOnTrain(this);
				
				if(currSpeed == 0) //Le train est arr�t� devant un feu.
					currPosOnRail = rail.getLongueur() - 1;
				else { //Le train doit changer de rail.
					if(rail.getjonction(1).railSuivant(rail) == null) { //Le train doit s'arr�ter � la but�e.
						currSpeed = 0;
						currPosOnRail = 0;
					}
					else {
						rail.enleverTrain(this);
						rail = rail.getjonction(1).railSuivant(rail);
						rail.ajoutTrain(this);
						currPosOnRail = rail.getLongueur() - (currSpeed - currPosOnRail) ;
					}
				}
			}

		}

		public String toString() {
			return "Je suis un train d'ID "+getId()+" de taille "+getSize()+" je circule dans le sens "+getDirection()+
				"a la vitesse "+getCurrentSpeed()+" je peux aller a la vitesse max de "+getMaxSpeed()+
				" je suis a la position"+getCurrPosOnRail()+" sur le rail "+getRail().toString();
		}		
}
